package dp.mobile.game;

import android.graphics.PointF;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import dp.mobile.glwrapper.GameRenderer;

public abstract class AdvancedTouchListener {
	private static final String TAG = "Advanced Touch Listener";
	public AdvancedTouchListener() {
		mLastPoint 	= new PointF[4];
		for (int i = 0; i < 4; ++i)
			mLastPoint[i] = new PointF();
	}
	
	public boolean onTouch(MotionEvent event) {		
		final int action = event.getAction();
		final int actionCode = action & MotionEvent.ACTION_MASK;
		final int touchCount = event.getPointerCount();
		GameRenderer renderer = GameRenderer.instance();
		
		final float nowX = event.getX();
		final float nowY = event.getY();
		
		final float scaleX = renderer.getScale().x;
		final float scaleY = renderer.getScale().y;
		
		switch (actionCode) {
		case MotionEvent.ACTION_DOWN :
			mClick = true;
			mLastPoint[0].x = nowX;
			mLastPoint[0].y = nowY;
			
			mDownEvent = event;
			
			mHandler.postDelayed(mLongPresser, 1500);
			
			mLastPoint[1].x = mLastPoint[0].x;
			mLastPoint[1].y = mLastPoint[0].y;
			break;
		case MotionEvent.ACTION_UP :
			// click
			onRelease(event);
			float dX = (nowX - mLastPoint[0].x) / scaleX;
			float dY = (nowY - mLastPoint[0].y) / scaleY;
			if (Math.sqrt(dX * dX + dY * dY) < 20 && mClick) {
				mClick = false;
				if (onClick(event))
					return true;
			}
			mClick = false;
			
			break;
		case MotionEvent.ACTION_POINTER_DOWN :
			Log.d(TAG, "Action Pointer Down, touch count = " + touchCount);
			
			if (touchCount == 2) {
				for (int i = 0; i < touchCount; ++i) {
					mLastPoint[i].x = event.getX(i);
					mLastPoint[i].y = event.getY(i);
				}
			}
			break;
			
		case MotionEvent.ACTION_MOVE :
			
			// if swipe
			if (touchCount == 1) {
				dX = nowX - mLastPoint[0].x;
				dY = nowY - mLastPoint[0].y;
				
				if (Math.sqrt(dX * dX + dY * dY) > 20) {
					mClick = false;
				}
				if (onSwipe(event))
					return true;
			}
			// if pinch
			else if (touchCount == 2) {
				if (onPinch(event))
					return true;
			}
			break;
			
		}
		
        return false;
	}


	protected Runnable mLongPresser = new Runnable() {
		@Override
		public void run() {
			if (mClick) {
				onLongPress(mDownEvent);
			}
		}
	};
	

	protected final Handler mHandler = new Handler();
	
	protected abstract boolean onClick(MotionEvent event);
	protected abstract boolean onSwipe(MotionEvent event);
	protected abstract boolean onPinch(MotionEvent event);
	protected abstract boolean onLongPress(MotionEvent event);
	protected abstract boolean onRelease(MotionEvent event);
	
	protected PointF[] mLastPoint;
	protected MotionEvent mDownEvent;
	private boolean mClick;
}
